Skip to content

fix(airc daemon): launcher cd's to cwd, skip AIRC_HOME (kills crashloop)#202

Merged
joelteply merged 2 commits intocanaryfrom
fix/daemon-scope-cwd
Apr 28, 2026
Merged

fix(airc daemon): launcher cd's to cwd, skip AIRC_HOME (kills crashloop)#202
joelteply merged 2 commits intocanaryfrom
fix/daemon-scope-cwd

Conversation

@joelteply
Copy link
Copy Markdown
Contributor

Summary

PR #201 follow-up. The HKCU-Run-key launcher .bat from #200 was still crashlooping every 4s on continuum-b69f's Windows because:

  1. AIRC_HOME=C:\...\continuum\.airc (Windows-form) made downstream airc paths fail on Git Bash's mixed fs view
  2. bash -lc re-exported PATH from login profile, churning the env we set in cmd

Fix

  • cd /d <cwd_win> from cmd, then run airc; detect_scope() finds <cwd>/.airc cleanly via pwd
  • Drop AIRC_HOME — rely on cwd-based scope detection
  • bash -c (not -lc) so login profile doesn't override env
  • Absolute Unix-form path to airc bin (cygpath -u) so bash-without-bashrc can find it without PATH

Verified

With #201 + this fix, airc daemon install from ~/continuum/ produces a launcher that runs airc connect cleanly and maintains the SSH tail. PR #200's RUNNING-PID detection now reflects a real working daemon.

🤖 Generated with Claude Code

….airc

PR #200 follow-up. _daemon_scope was returning ${AIRC_HOME:-$HOME/.airc}
unconditionally, but actual user state lives in $cwd/.airc per
detect_scope(). So 'airc daemon install' from ~/continuum/ captured
the wrong scope (~/.airc, empty), spawned a monitor that connected to
nothing, user appeared offline despite 'RUNNING (PID xxx)' in status.

Mirror detect_scope's logic exactly: AIRC_HOME if set, else cwd/.airc.
Now 'airc daemon install' from a project dir captures THAT dir's
.airc as the daemon's scope, launcher .bat sets AIRC_HOME=that, the
spawned airc connect uses the right room state.

Joel 2026-04-28 ~01:05Z caught this: 'lol obv if it worked you would
have a monitor and be online. FAIL'.
…ew fix)

Daemon installed via PR #200/#201 was still crashlooping (every 4s)
because the launcher .bat set AIRC_HOME to a Windows-form path
(C:\Users\green\continuum\.airc) which Git Bash's airc binary
couldn't traverse cleanly downstream. Plus 'bash -lc' was reading
login profile and re-exporting PATH which churned env.

Restructured launcher .bat:
1. 'cd /d <cwd_win>' from cmd.exe so the bash subprocess inherits
   the project dir as pwd. detect_scope() then returns <cwd>/.airc
   the same way it does in the user's interactive shell.
2. Drop AIRC_HOME entirely — let detect_scope work normally.
3. 'bash -c' not 'bash -lc' — non-login skips profile, keeps the
   env we set in cmd uncorrupted.
4. Absolute Unix-form path to airc (cygpath -u) — bash -c doesn't
   read ~/.bashrc, so PATH may not include ~/.local/bin.
5. Errors log to daemon.err relative to cwd (already cd'd into it).

Joel 2026-04-28 caught both the wrong-scope (PR #201) and now the
crashloop. Verified locally: with this launcher shape, airc connect
runs to completion + maintains the SSH tail to the host.
Copilot AI review requested due to automatic review settings April 28, 2026 06:04
@joelteply joelteply merged commit d4c5e60 into canary Apr 28, 2026
8 checks passed
@joelteply joelteply deleted the fix/daemon-scope-cwd branch April 28, 2026 06:05
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the Windows “HKCU Run-key” daemon launcher to avoid a crashloop caused by Windows-form paths and environment churn when invoking Git Bash, by making the launcher run from the install-time project directory and relying on cwd-based scope detection.

Changes:

  • Update _daemon_scope() to mirror detect_scope() (cwd-based default) when AIRC_HOME is not set.
  • Adjust the generated Windows launcher .bat to cd /d into the install-time cwd, drop AIRC_HOME, switch bash -lcbash -c, and invoke airc via an absolute Unix-form path.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread airc

# The scope the daemon will run under. If AIRC_HOME is set at install time,
# that's recorded in the unit/plist so future starts use the same scope.
# The scope the daemon will run under. Mirrors detect_scope() (line 135)
Copy link

Copilot AI Apr 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment references a specific source line number (“Mirrors detect_scope() (line 135)”), which will drift as the file changes and can become misleading. Prefer describing the relationship without hard-coding a line number (or reference the function name only).

Suggested change
# The scope the daemon will run under. Mirrors detect_scope() (line 135)
# The scope the daemon will run under. Mirrors detect_scope()

Copilot uses AI. Check for mistakes.
Comment thread airc
REM AIRC daemon launcher — generated by 'airc daemon install' on Windows.
REM Runs airc connect under bash, restarting on exit. Logs to daemon.log.
set AIRC_HOME=$scope_win
cd /d "$cwd_win"
Copy link

Copilot AI Apr 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cd /d "$cwd_win" is not checked for failure. If the directory is missing/moved (or the path is invalid at logon), the launcher will continue in whatever the default working directory is (often System32), causing scope detection and log placement to be wrong (and potentially failing due to permissions). Consider aborting the loop when cd fails (or falling back to a safe directory and logging the error).

Copilot uses AI. Check for mistakes.
Comment thread airc
"$bash_exe" -lc "exec '$airc_bin_win' connect"
echo [%date% %time%] airc connect exited. Restarting in 5s. >> "$scope_win\\daemon.err"
"$bash_exe" -c "exec '$airc_bin_unix' connect"
echo [%date% %time%] airc connect exited. Restarting in 5s. >> daemon.err
Copy link

Copilot AI Apr 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The restart message is appended to daemon.err in the project directory, but the rest of the daemon UX (status output) points users at $scope/daemon.err (i.e., <cwd>/.airc/daemon.err). This mismatch makes it look like errors are missing. Write the restart log into the same $scope/daemon.err location (e.g., via %CD%\.airc\daemon.err after the cd, or an absolute path based on the recorded scope).

Suggested change
echo [%date% %time%] airc connect exited. Restarting in 5s. >> daemon.err
echo [%date% %time%] airc connect exited. Restarting in 5s. >> "%CD%\.airc\daemon.err"

Copilot uses AI. Check for mistakes.
Comment thread airc
Comment on lines +5054 to +5057
cd /d "$cwd_win"
set AIRC_BACKGROUND_OK=1
:loop
"$bash_exe" -lc "exec '$airc_bin_win' connect"
echo [%date% %time%] airc connect exited. Restarting in 5s. >> "$scope_win\\daemon.err"
"$bash_exe" -c "exec '$airc_bin_unix' connect"
Copy link

Copilot AI Apr 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This launcher now always relies on cwd-based scope detection and no longer sets AIRC_HOME for the daemon process. That means installs done with AIRC_HOME set (which _daemon_scope() still supports, and which launchd/systemd persist) will behave differently on Windows: the monitor will run against <cwd>/.airc instead of the intended overridden scope. Consider preserving AIRC_HOME for the Windows launcher too (but pass it in POSIX form for Git Bash), and/or derive the cd target from the recorded scope rather than the install-time pwd.

Copilot uses AI. Check for mistakes.
joelteply added a commit that referenced this pull request Apr 28, 2026
 target 2, net -40) (#209)

refactor(airc): _daemon_install_done helper + trim duplicated comments (#205 target 2)

Three platform daemon installers (launchd/systemd/schtasks) duplicated
the same 5-line "Loaded into X / airc will auto-start / Logs / Status"
print block. Plus the schtasks function had ~30 lines of comment
paragraphs duplicating commit-history context (#200/#202 explanations).

Now: one `_daemon_install_done` helper for the print footer, called
by all three installers. Schtasks comment block trimmed to a 4-line
summary that points at PR #202 for the bug-history detail.

Behavior unchanged on every platform — same plist/unit/.bat content,
same registration calls, same status output (just printed via the helper).

#205 target 2 of 6.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants